package com.socket.server.request;

import cn.hutool.core.io.resource.BytesResource;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.socket.server.config.properties.AListProperties;
import com.socket.server.custom.exception.BizException;
import com.socket.server.custom.storage.ResourceStorage;
import com.socket.server.model.enmus.FileType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.PostConstruct;

/**
 * Alist API（实验性）
 */
@Slf4j
@RequiredArgsConstructor
public class AListRequest implements ResourceStorage {
    private final AListProperties properties;
    private String token;

    public String upload(FileType type, byte[] bytes, String hash) {
        // 拼接保存路径
        String path = StrUtil.format("{}/{}/{}", properties.getRoot(), type.getKey(), hash);
        // 发起Alist请求
        String body = HttpRequest.put(properties.getUploadURL())
                .auth(token)
                .header("File-Path", URLUtil.encode(path))
                .form("file", new BytesResource(bytes, hash))
                .execute()
                .body();
        // 解析结果
        JSONObject json = JSONUtil.parseObj(body);
        // 登录信息过期
        if (json.getInt("code") != 200) {
            log.warn("AList上传文件出错时：{}", json.getStr("message"));
            throw new BizException("文件上传服务暂时关闭");
        }
        return path;
    }

    public String getOpenURL(String url) {
        // 构建请求参数
        JSONObject param = new JSONObject();
        param.set("path", url);
        // 发起Alist请求
        String body = HttpRequest.put(properties.getDownloadURL())
                .auth(token)
                .body(param.toString())
                .execute()
                .body();
        // 解析结果
        JSONObject json = JSONUtil.parseObj(body);
        if (json.getInt("code") != 200) {
            log.info("解析URL失败：{}", url);
            return null;
        }
        return json.getJSONObject("data").getStr("raw_url");
    }

    /**
     * 刷新AList令牌
     */
    @PostConstruct
    @Scheduled(cron = "0 0 0/3 * * ?")
    private void flushToken() {
        String body = HttpRequest.post(properties.getAuthURL())
                .body(JSONUtil.toJsonStr(properties))
                .execute()
                .body();
        JSONObject object = JSONUtil.parseObj(body);
        if (object.getInt("code") != 200) {
            log.warn("获取AList令牌出错：{}", object.getStr("message"));
            return;
        }
        this.token = object.getJSONObject("data").getStr("token");
        log.debug("AList令牌刷新成功: {}", token);
    }
}
